home *** CD-ROM | disk | FTP | other *** search
/ ASME's Mechanical Engine…ing Toolkit 1997 December / ASME's Mechanical Engineering Toolkit 1997 December.iso / c_lang / sc.zoo / range.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-06-03  |  5.3 KB  |  255 lines

  1.  
  2. /*    SC    A Spreadsheet Calculator
  3.  *        Range Manipulations
  4.  *
  5.  *              Robert Bond, 4/87
  6.  *
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <curses.h>
  11. #include <ctype.h>
  12. #include "sc.h"
  13.  
  14. #ifdef BSD42
  15. #include <strings.h>
  16. #else
  17. #ifndef SYSIII
  18. #include <string.h>
  19. #endif
  20. #endif
  21.  
  22. static struct range *rng_base;
  23.  
  24. add_range(name, left, right, is_range)
  25. char *name;
  26. struct ent_ptr left, right;
  27. int is_range;
  28. {
  29.     struct range *r;
  30.     register char *p;
  31.     int len;
  32.     int minr,minc,maxr,maxc;
  33.     int minrf, mincf, maxrf, maxcf;
  34.  
  35.     if (left.vp->row < right.vp->row) {
  36.     minr = left.vp->row; minrf = left.vf & FIX_ROW;
  37.     maxr = right.vp->row; maxrf = right.vf & FIX_ROW;
  38.     } else {
  39.     minr = right.vp->row; minrf = right.vf & FIX_ROW;
  40.     maxr = left.vp->row; maxrf = right.vf & FIX_ROW;
  41.     } 
  42.  
  43.     if (left.vp->col < right.vp->col) {
  44.     minc = left.vp->col; mincf = left.vf & FIX_COL;
  45.     maxc = right.vp->col; maxcf = right.vf & FIX_COL;
  46.     } else {
  47.     minc = right.vp->col; mincf = right.vf & FIX_COL;
  48.     maxc = left.vp->col; maxcf = left.vf & FIX_COL;
  49.     } 
  50.  
  51.     left.vp = lookat(minr, minc);
  52.     left.vf = minrf | mincf;
  53.     right.vp = lookat(maxr, maxc);
  54.     right.vf = maxrf | maxcf;
  55.  
  56.     if (find_range(name, strlen(name), (struct ent *)0, (struct ent *)0)) {
  57.     error("Error: range name already defined");
  58.     xfree(name);
  59.     return;
  60.     }
  61.  
  62.     if (strlen(name) <= 2) {
  63.     error("Invalid range name - too short");
  64.     xfree(name);
  65.     return;
  66.     }
  67.  
  68.     for(p=name, len=0; *p; p++, len++)
  69.     if (!((isalpha(*p) && (len<=2)) ||
  70.         ((isdigit(*p) || isalpha(*p) || (*p == '_')) && (len>2)))) {
  71.         error("Invalid range name - illegal combination");
  72.         xfree(name);
  73.         return;
  74.         }
  75.  
  76.     r = (struct range *)xmalloc((unsigned)sizeof(struct range));
  77.     r->r_name = name;
  78.     r->r_left = left;
  79.     r->r_right = right;
  80.     r->r_next = rng_base;
  81.     r->r_prev = 0;
  82.     r->r_is_range = is_range;
  83.     if (rng_base)
  84.         rng_base->r_prev = r;
  85.     rng_base = r;
  86. }
  87.  
  88. del_range(left, right)
  89. struct ent *left, *right;
  90. {
  91.     register struct range *r;
  92.     int minr,minc,maxr,maxc;
  93.  
  94.     minr = left->row < right->row ? left->row : right->row;
  95.     minc = left->col < right->col ? left->col : right->col;
  96.     maxr = left->row > right->row ? left->row : right->row;
  97.     maxc = left->col > right->col ? left->col : right->col;
  98.  
  99.     left = lookat(minr, minc);
  100.     right = lookat(maxr, maxc);
  101.  
  102.     if (!(r = find_range((char *)0, 0, left, right))) 
  103.     return;
  104.  
  105.     if (r->r_next)
  106.         r->r_next->r_prev = r->r_prev;
  107.     if (r->r_prev)
  108.         r->r_prev->r_next = r->r_next;
  109.     else
  110.     rng_base = r->r_next;
  111.     xfree((char *)(r->r_name));
  112.     xfree((char *)r);
  113. }
  114.  
  115. clean_range()
  116. {
  117.     register struct range *r;
  118.     register struct range *nextr;
  119.  
  120.     r = rng_base;
  121.     rng_base = 0;
  122.  
  123.     while (r) {
  124.     nextr = r->r_next;
  125.     xfree((char *)(r->r_name));
  126.     xfree((char *)r);
  127.     r = nextr;
  128.     }
  129. }
  130.  
  131. /* Match on name or lmatch, rmatch */
  132.  
  133. struct range *
  134. find_range(name, len, lmatch, rmatch)
  135. char *name;
  136. int len;
  137. struct ent *lmatch;
  138. struct ent *rmatch;
  139. {
  140.     struct range *r;
  141.     register char *rp, *np;
  142.     register int c;
  143.  
  144.     if (name) {
  145.     for (r = rng_base; r; r = r->r_next) {
  146.         for (np = name, rp = r->r_name, c = len;
  147.          c && *rp && (*rp == *np);
  148.          rp++, np++, c--) /* */;
  149.         if (!c && !*rp)
  150.         return(r);
  151.     }
  152.     return(0);
  153.     }
  154.  
  155.     for (r = rng_base; r; r= r->r_next) {
  156.     if ((lmatch == r->r_left.vp) && (rmatch == r->r_right.vp)) 
  157.         return(r);
  158.     }
  159.     return(0);
  160. }
  161.  
  162. sync_ranges()
  163. {
  164.     register struct range *r;
  165.  
  166.     r = rng_base;
  167.     while(r) {
  168.     r->r_left.vp = lookat(r->r_left.vp->row, r->r_left.vp->col);
  169.     r->r_right.vp = lookat(r->r_right.vp->row, r->r_right.vp->col);
  170.     r = r->r_next;
  171.     }
  172. }
  173.  
  174. write_range(f)
  175. FILE *f;
  176. {
  177.     register struct range *r;
  178.  
  179.     for (r = rng_base; r; r = r->r_next) {
  180.     (void) fprintf(f, "define \"%s\" %s%s%s%d",
  181.             r->r_name,
  182.             r->r_left.vf & FIX_COL ? "$":"",
  183.             coltoa(r->r_left.vp->col), 
  184.             r->r_left.vf & FIX_ROW ? "$":"",
  185.             r->r_left.vp->row);
  186.     if (r->r_is_range)
  187.         (void) fprintf(f, ":%s%s%s%d\n",
  188.                 r->r_right.vf & FIX_COL ? "$":"",
  189.                 coltoa(r->r_right.vp->col), 
  190.                 r->r_right.vf & FIX_ROW ? "$":"",
  191.                 r->r_right.vp->row);
  192.     else
  193.         (void) fprintf(f, "\n");
  194.     }
  195. }
  196.  
  197. list_range(f)
  198. FILE *f;
  199. {
  200.     register struct range *r;
  201.  
  202.     for (r = rng_base; r; r = r->r_next) {
  203.     (void) fprintf(f, "%-30s %s%s%s%d",
  204.                 r->r_name,
  205.                 r->r_left.vf & FIX_COL ? "$":"",
  206.                 coltoa(r->r_left.vp->col), 
  207.                 r->r_left.vf & FIX_ROW ? "$":"",
  208.                 r->r_left.vp->row);
  209.     if (r->r_is_range)
  210.         (void) fprintf(f, ":%s%s%s%d\n",
  211.                 r->r_right.vf & FIX_COL ? "$":"",
  212.                 coltoa(r->r_right.vp->col), 
  213.                 r->r_right.vf & FIX_ROW ? "$":"",
  214.                 r->r_right.vp->row);
  215.     else
  216.         (void) fprintf(f, "\n");
  217.     }
  218. }
  219.  
  220. char *
  221. v_name(row, col)
  222. int row, col;
  223. {
  224.     struct ent *v;
  225.     struct range *r;
  226.     static char buf[20];
  227.  
  228.     v = lookat(row, col);
  229.     if (r = find_range((char *)0, 0, v, v)) {
  230.     return(r->r_name);
  231.     } else {
  232.         (void) sprintf(buf, "%s%d", coltoa(col), row);
  233.     return(buf);
  234.     }
  235. }
  236.  
  237. char *
  238. r_name(r1, c1, r2, c2)
  239. int r1, c1, r2, c2;
  240. {
  241.     struct ent *v1, *v2;
  242.     struct range *r;
  243.     static char buf[100];
  244.  
  245.     v1 = lookat(r1, c1);
  246.     v2 = lookat(r2, c2);
  247.     if (r = find_range((char *)0, 0, v1, v2)) {
  248.     return(r->r_name);
  249.     } else {
  250.         (void) sprintf(buf, "%s", v_name(r1, c1));
  251.     (void) sprintf(buf+strlen(buf), ":%s", v_name(r2, c2));
  252.     return(buf);
  253.     }
  254. }
  255.